
/**		
 * 
 *	uk.co.lmfm.guppy.model.LibraryProxy
 *	
 *	@version 1.00 | Jan 21, 2010
 *	@author Justin Windle
 *  
 **/
 
package uk.co.lmfm.guppy.model 
{
	import uk.co.lmfm.guppy.application.enum.ApplicationConstants;
	import uk.co.lmfm.guppy.model.vo.AlertVO;
	import uk.co.lmfm.guppy.model.vo.ClassLibraryVO;
	import uk.co.lmfm.guppy.model.vo.ConfigVO;
	import uk.co.lmfm.guppy.model.vo.CoreLibraryVO;
	import uk.co.lmfm.guppy.model.vo.FlashPlayerVO;
	import uk.co.lmfm.guppy.model.vo.FlexSDKVO;
	import uk.co.lmfm.guppy.model.vo.ProjectTemplateVO;
	import uk.co.lmfm.guppy.model.vo.SettingsVO;
	import uk.co.lmfm.util.FileUtil;
	import uk.co.lmfm.util.StringUtil;

	import org.osflash.thunderbolt.Logger;
	import org.puremvc.as3.multicore.interfaces.IProxy;
	import org.puremvc.as3.multicore.patterns.proxy.Proxy;

	import flash.desktop.NativeProcess;
	import flash.desktop.NativeProcessStartupInfo;
	import flash.filesystem.File;

	/**
	 * LibraryProxy
	 */
	public class LibraryProxy extends Proxy implements IProxy 
	{
		//	----------------------------------------------------------------
		//	CONSTANTS
		//	----------------------------------------------------------------

		public static const NAME : String = "LibraryProxy";

		private static const CONFIG_PATH : String = "config.xml";		private static const GLOBAL_ANT_PROPERTIES_TEMPLATE_PATH : String = "ANT/settings/.fdt.properties";		private static const GLOBAL_ANT_PROPERTIES_PATH : String = "ANT/settings/fdt.properties";

		//	----------------------------------------------------------------
		//	PRIVATE MEMBERS
		//	----------------------------------------------------------------

		private var _data : XML;
		private var _config : ConfigVO;
		private var _flexSDKs : Vector.<FlexSDKVO>;
		private var _players : Vector.<FlashPlayerVO>;
		private var _coreLibs : Vector.<CoreLibraryVO>;
		private var _classLibs : Vector.<ClassLibraryVO>;
		private var _templates : Vector.<ProjectTemplateVO>;
		private var _libraryPath : String;

		//	----------------------------------------------------------------
		//	CONSTRUCTOR
		//	----------------------------------------------------------------

		public function LibraryProxy(data : Object = null)
		{
			super(NAME, data);
		}

		//	----------------------------------------------------------------
		//	PUBLIC METHODS
		//	----------------------------------------------------------------

		public function setLibraryPath(path : String) : void
		{
			_libraryPath = path;
			loadConfig();
		}

		public function loadConfig() : void
		{
			if(_libraryPath)
			{
				var library : File = new File().resolvePath(_libraryPath);
				var configFile : File = library.resolvePath(CONFIG_PATH);
			
				_data = FileUtil.readXML(configFile);
				
				Logger.debug("Config: " + _data);
				
				getConfig();
			}
			else
			{
				Logger.error("Cannot load config.xml. No library path set.");
			}
		}

		/**
		 * Called after each checkout
		 * @see CheckoutCompleteCommand
		 */

		public function configureLibrary(settings : SettingsVO) : void
		{
			var library : File = new File().resolvePath(_libraryPath);
			var properties : File = library.resolvePath(GLOBAL_ANT_PROPERTIES_PATH);			var template : File = library.resolvePath(GLOBAL_ANT_PROPERTIES_TEMPLATE_PATH);
			
			var sdks : String = '';
			
			for (var i : int = 0;i < _config.sdks.length;i++)
			{
				sdks += _config.sdks[i].ant + "\t\t= " + StringUtil.stripSlashes(settings.libraryPath + "/SDK/" + _config.sdks[i].id) + "\n";
			}
			
			if(template.exists)
			{
				var ant : String = FileUtil.readUTF(template);
				
				ant = ant
						.replace(/\${workspace.path}/g, settings.workspaceLocation)						.replace(/\${workspace.backup}/g, "TODO: backup location")						.replace(/\${flex.sdk.configured}/g, sdks)						.replace(/\${app.flash.player}/g, settings.flashPlayer)
						.replace(/\${app.flash.ide}/g, settings.flashIDE);
				
				FileUtil.writeUTF(ant, properties);
				
				Logger.info("Global ANT properties updated: " + ant);
			}
			else
			{
				Logger.error("Error writing to global ANT properties file. File doesn't exist. Please check your library for: " + GLOBAL_ANT_PROPERTIES_PATH);
			}
			
			var userDir : File = library.resolvePath("AS3 (" + settings.username + ")");
			
			if(!userDir.exists)
			{
				Logger.info("Creating user library: " + userDir.nativePath);
				userDir.createDirectory();
				
				var openStart : NativeProcessStartupInfo = new NativeProcessStartupInfo();
				
				openStart.executable = new File("/usr/bin/open");
				openStart.arguments = new Vector.<String>();
				
				openStart.arguments.push("-a");
				openStart.arguments.push("finder");				openStart.arguments.push(userDir.nativePath);
				
				var openProcess : NativeProcess = new NativeProcess();
				openProcess.start(openStart);
				
				var alert : AlertVO = new AlertVO();
				alert.title = "Add your class libraries";
				alert.message = "Your personal class library path is '" + userDir.name + "' (this should have opened in a new Finder window).\nYou can drop your favourite class libraries into here to use with the project wizard";
				
				sendNotification(ApplicationConstants.SHOW_ALERT, alert);
			}
		}

		//	----------------------------------------------------------------
		//	PRIVATE METHODS
		//	----------------------------------------------------------------

		private function getConfig() : ConfigVO
		{
			_config = new ConfigVO();
			
			// Must be in correct order!

			_config.sdks = flexSDKs;			_config.coreLibraries = coreLibraries;
			_config.projectTemplates = projectTemplates;
			_config.playerVersions = playerVersions;
			_config.classLibraries = classLibraries;
			
			return _config;
		}

		private function getFlexSDKs() : Vector.<FlexSDKVO>
		{
			_flexSDKs = new Vector.<FlexSDKVO>();
			
			var list : XMLList = _data..sdk;
			var len : int = list.length();
			var i : int;
			
			for (i = 0;i < len;i++) 
			{
				_flexSDKs[i] = new FlexSDKVO();
				
				_flexSDKs[i].id = list[i].@id;
				_flexSDKs[i].path = list[i].@path;
				_flexSDKs[i].ant = list[i].@ant;				_flexSDKs[i].url = list[i].@url;
			}
			
			return _flexSDKs;
		}

		private function getCoreLibraries() : Vector.<CoreLibraryVO>
		{
			_coreLibs = new Vector.<CoreLibraryVO>();
			
			var list : XMLList = _data..corelib;
			var len : int = list.length();
			var i : int;
			
			for (i = 0;i < len;i++) 
			{
				_coreLibs[i] = new CoreLibraryVO();
				
				_coreLibs[i].name = list[i].@name;				_coreLibs[i].path = list[i].@path;				_coreLibs[i].type = list[i].@type;
				_coreLibs[i].sdk = getSDKByPath(list[i].@path);				_coreLibs[i].custom = parseBool(list[i].@custom);
			}
			
			return _coreLibs;
		}

		private function getPlayerVersions() : Vector.<FlashPlayerVO>
		{
			_players = new Vector.<FlashPlayerVO>();
			
			var list : XMLList = _data..player;
			var len : int = list.length();
			var i : int;
			
			for (i = 0;i < len;i++) 
			{
				_players[i] = new FlashPlayerVO();
				
				_players[i].name = list[i].@name;				_players[i].version = list[i].@version;				_players[i].corelib = getCoreLibByName(list[i].@corelib);				_players[i].template = getTemplateByName(list[i].@template);				_players[i].isDefault = parseBool(list[i].@isDefault);
			}
			
			return _players;
		}

		private function getClassLibraries() : Vector.<ClassLibraryVO>
		{
			_classLibs = new Vector.<ClassLibraryVO>();
			
			var list : XMLList = _data..library;
			var len : int = list.length();
			var i : int;
			
			for (i = 0;i < len;i++) 
			{
				_classLibs[i] = new ClassLibraryVO();
				
				_classLibs[i].name = list[i].@name;
				_classLibs[i].path = list[i].@path;
				_classLibs[i].version = list[i].@version;
			}
			
			return _classLibs;
		}

		private function getProjectTemplates() : Vector.<ProjectTemplateVO>
		{
			_templates = new Vector.<ProjectTemplateVO>();
			
			var list : XMLList = _data..template;
			var len : int = list.length();
			var i : int;
			
			for (i = 0;i < len;i++) 
			{
				_templates[i] = new ProjectTemplateVO();
				
				_templates[i].name = list[i].@name;
				_templates[i].path = list[i].@path;
				
				// TODO add props
			}
			
			return _templates;
		}

		private function getCoreLibByName(name : String) : CoreLibraryVO
		{
			for (var i : int = 0;i < _coreLibs.length;i++)
			{
				if(_coreLibs[i].name == name) return _coreLibs[i];
			}
			
			return null;
		}

		private function getTemplateByName(name : String) : ProjectTemplateVO
		{
			for (var i : int = 0;i < _templates.length;i++)
			{
				if(_templates[i].name == name) return _templates[i];
			}
			
			return null;
		}

		private function getSDKByPath(path : String) : FlexSDKVO
		{
			for (var i : int = 0;i < _flexSDKs.length;i++)
			{
				if(_flexSDKs[i].path == path) return _flexSDKs[i];
			}
			
			// Default to first SDK

			return _flexSDKs[0];
		}

		private function parseBool(val : *) : Boolean
		{
			if(val == null || val == undefined || val == false || val == 0) return false;
			var str : String = String(val).toLowerCase(); 
			if(str == "false" || str == "no") return false;
			return true;
		}

		//	----------------------------------------------------------------
		//	PUBLIC ACCESSORS
		//	----------------------------------------------------------------

		public function get config() : ConfigVO
		{
			return _config || getConfig();
		}

		public function get flexSDKs() : Vector.<FlexSDKVO>
		{
			return _flexSDKs || getFlexSDKs();
		}

		public function get coreLibraries() : Vector.<CoreLibraryVO>
		{
			return _coreLibs || getCoreLibraries();
		}

		public function get playerVersions() : Vector.<FlashPlayerVO>
		{
			return _players || getPlayerVersions();
		}

		public function get classLibraries() : Vector.<ClassLibraryVO>
		{
			return _classLibs || getClassLibraries();
		}

		public function get projectTemplates() : Vector.<ProjectTemplateVO>
		{
			return _templates || getProjectTemplates();
		}
	}
}
